import scorePanel from "./scorePanel"
import config from "../../config"
import food from './food'
import snake from './snake'

export default class GameController {
  // 游戏状态
  isGaming: boolean = true
  // 移动方向
  direction: string = ''
  // 移动速度
  speed: number = config.snake.speed
  // 蛇的位置包括头部和身体
  locations: { x: number; y: number }[] = [{x: 0, y: 0}]

  snake: HTMLElement
  header: HTMLElement

  constructor() {
    this.snake = document.querySelector("#snake")!
    this.header = document.querySelector("#header")!

    this.init()
  }

  // 初始化
  init() {
    this.keyboardEvent()
    this.move()
  }

  // 键盘监听事件
  keyboardEvent() {
    document.addEventListener("keydown", this.handleKeyboard.bind(this))
  }

  // 键盘监听事件回调
  handleKeyboard(e: KeyboardEvent) {
    const obj = {
      w: 's',
      s: 'w',
      a: 'd',
      d: 'a'
    }
    // 防止反向移动
    if (obj[this.direction as keyof typeof obj] === e.key && this.locations.length > 2) return
    this.direction = e.key
  }

  // 移动
  move() {
    let x = this.header.offsetLeft
    let y = this.header.offsetTop

    switch (this.direction) {
      case 'w':
        y -= this.speed
        break
      case 's':
        y += this.speed
        break
      case 'd':
        x += this.speed
        break
      case 'a':
        x -= this.speed
    }

    if (!this.isTouch(x, y)) {
      // 头部移动
      this.header.style.left = x + "px"
      this.header.style.top = y + "px"
      // 记录头部位置
      this.locations[0] = { x, y }
      // 身体移动
      this.moveBody()
    } else {
      this.isGaming = false
      alert('游戏结束了')
    }

    // 食物检测
    if (this.isTouchFood(x, y)) {
      // 分数+1
      scorePanel.setScore()
      // 移除食物
      food.removeFood(x, y)
      // 添加坐标 添加的坐标是上一个身体的坐标
      this.locations[this.locations.length] = this.locations[this.locations.length - 1]
      // 添加身体长度
      this.addBody()
    }
    // 游戏是否结束
    this.isGaming ? setTimeout(() => {
      this.move()
    }, (config.score.maxLevel - scorePanel.level + 1) * 70) : null
  }

  // 墙体碰撞检测
  isTouch(x: number, y: number) {
    const model = config.snake.model
    const stageWidth = config.stage.width
    const stageHeight = config.stage.height
    const isTouch = (x < 0 || x >= stageWidth - model || y < 0 || y >= stageHeight - model)
    // 蛇身体碰撞检测
    const isTouchBody = this.locations.filter((item, index) => {
      return index !== 0 && item.x === x && item.y === y
    }).length > 0
    return isTouch || isTouchBody
  }

  // 食物碰撞
  isTouchFood(x: number, y: number) {
    const foodPositions = food.positionList
    // 查看是否有位置相同的点
    return foodPositions.some(item => {
      return item.x === x && item.y === y
    })
  }

  // 吃到食物 添加身体
  addBody() {
    // 创建div
    const body = document.createElement('div')
    // 获取最后一块身体的坐标
    const bodyPosition = this.locations[this.locations.length - 1]
    // 为蛇的身体设置样式
    snake.setSnakeStyle(body, bodyPosition)
  }

  // 身体移动
  moveBody() {
    const snakeObj = snake.bodies
    // 从后往前移动
    for (let i = snakeObj.length - 1; i > 0; i--) {
      // 获取身体
      const body = snakeObj[i]
      // 获取上一个身体的位置
      const position = this.locations[i - 1]
      body.style.left = position.x + 'px'
      body.style.top = position.y + 'px'
      // 记录位置
      this.locations[i] = position
    }
  }

}
